﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BPM.Web;
using BPM.Common;
using BPM.Service;
using BPM.Entity;

namespace BPM.Controllers
{
	public class AssembleController : InternalViewController
	{
		#region AddProductDefinitionAssemble

		[HttpGet]
		public ActionResult AddProductDefinitionAssemble()
		{
			this.ViewData["Barcode"] = new BarcodeService().RandomBarcodeNumber();
			return View();
		}

		public ActionResult AJAX_AddProductDefinition(
			string barcode, string name, string description,
			string materialAmount
			)
		{
			var amount = ReadMaterialsAmount(materialAmount);
			var res = CreateProductDefinition(barcode, name, description, amount, this.CurrentUser);

			return Json(res);
		}

		private static Result CreateProductDefinition(string barcode, string name, string description, IDictionary<int, int> amount, User curUser)
		{
			if (amount.Sum(kv => kv.Value) == 0) return "物料数为0，添加失败。";
			if (string.IsNullOrWhiteSpace(barcode)) return "条码为空，添加失败。";
			if (string.IsNullOrWhiteSpace(name)) return "名称为空，添加失败。";
			description = description ?? string.Empty;

			var product = new ProductAssembleDefinition()
			{
				Barcode = new Barcode()
				{
					BarcodeCategoryId = SysBarcodeCategories.MaterialDefinition.Id,
					Number = barcode
				},
				Name = name,
				Description = description,
				UserId = curUser.Id,
				CreatedTime = DateTime.Now,
				ItemList = new List<ProductAssembleDefinitionItem>()
			};

			foreach (var kv in amount)
			{
				if (kv.Value > 0)
				{
					product.ItemList.Add(new ProductAssembleDefinitionItem()
					{
						MaterialDefinitionId = kv.Key,
						Amount = kv.Value,
						ProductAssembleDefinition = product
					});
				}
			}

			var svc = new ProductAssembleDefinitionService();
			var res = svc.Save(product);

			return res;
		}

		private IDictionary<int, int> ReadMaterialsAmount(string materialAmount)
		{
			var dic = new Dictionary<int, int>();//id:amount
			var items = materialAmount.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
			foreach (var item in items)
			{
				var values = item.Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
				var id = ParsePositiveInt(values[0]);
				var amount = ParsePositiveInt(values[1]);
				if (id > 0 && amount > 0)
				{
					dic[id] = amount;
				}
			}
			return dic;
		}

		#endregion

		[HttpGet]
		public ActionResult ProductDefinitionAssemble(int id)
		{
			var svc = new ProductAssembleDefinitionService();
			var entity = svc.GetById(id);
			if (entity == null) return RedirectToAction(a => a.InternalDefaultView.Default);

			return View(entity);
		}

		[HttpGet]
		public ActionResult ProductDefinitionList()
		{
			this.ViewData["List"] = new ProductAssembleDefinitionService().GetAll();
			return View();
		}

		/// <summary>
		/// 现有产品定义列表
		/// </summary>
		/// <returns></returns>
		[HttpGet]
		public ActionResult ProductAssemble(int productId)
		{
			var product = new ProductAssembleDefinitionService().GetById(productId);
			if (product == null) return RedirectToAction(a => a.InternalDefaultView.Default);

			this.ViewData["Product"] = product;
			this.ViewData["ProductJson"] = JsonString(new
			{
				id = product.Id,
				materials = product.ItemList.Select(m => new
				{
					id = m.MaterialDefinitionId,
					barcode = m.MaterialDefinition.Barcode.Number,
					amountNeed = m.Amount
				}).ToArray()
			});

			return View();
		}

		public ActionResult AJAX_SubmitProductAssemble(int productId)
		{
			var res = AddProductAssemble(productId, this.CurrentUser);

			return Json(res);
		}

		private static Result AddProductAssemble(int productAssembleDefinitionId, User curUser)
		{
			var productDef = new ProductAssembleDefinitionService().GetById(productAssembleDefinitionId);
			if (productDef == null) return "没有找到对应的产品组装定义！";

			var product = new Entity.ProductAssemble()
			{
				ProductAssembleDefinitionId = productAssembleDefinitionId,
				UserId = curUser.Id,
				ItemList = new List<ProductAssembleItem>(),
				AssembleTime = DateTime.Now
			};

			foreach (var materialNeed in productDef.ItemList)
			{
				product.ItemList.Add(new ProductAssembleItem()
				{
					Amount = materialNeed.Amount,
					MaterialDefinitionId = materialNeed.MaterialDefinitionId,
					ProductAssemble = product
				});
			}

			var svc = new ProductAssembleService();
			var res = svc.Save(product);
			return res;
		}
	}

	public class AssembleControllerActions : ControllerDefinition<AssembleController>
	{
		public readonly string AddProductDefinitionAssemble = "AddProductDefinitionAssemble";
		public readonly string ProductDefinitionAssemble = "ProductDefinitionAssemble";
		public readonly string ProductDefinitionList = "ProductDefinitionList";
		public readonly string ProductAssemble = "ProductAssemble";
	}
}